GeometryBuffer <- function(obj, radius, side ="full", segments = 12L, end = "round", unit = "meter", prj = NULL){
  
  if(is.null(obj)){
    stop("obj is null.")
  }
  if(!.IsGeoTypeValid(GetType(obj))){
    stop("Unsupported SuperMap geometry type.")
  }
  if(!is.numeric(radius) && !is.vector(radius) && !is.list(radius)){
    stop("radius must be numberic, vector or list.")
  }
  if(is.numeric(radius) && (is.na(radius) || radius == 0)){
    stop("radius must be valid")
  } else if(is.vector(radius) || is.list(radius)){
    if(length(radius) == 0){
      stop("radius is a vector, size must be greater than 0.")
    }
  }
  
  if(is.null(side)){
    stop("side is null. must be 'full', 'left', 'right' or 'differ'")
  }
  valid.side = c( "full", "left", "right" , "differ" )
  if(length(valid.side[valid.side == tolower(side)]) == 0){
    stop("invalid side. side must be 'full', 'left', 'right' or 'differ'")
  }
  
  if(is.null(end)){
    stop("end is null. must be 'round', 'flat' ")
  }
  
  valid.end = c( "round", "flat" )
  if(length(valid.end[valid.end == tolower(end)]) == 0){
    stop("invalid end type, end type must be 'round', 'flat' ")
  }
  
  if(is.null(unit)){
    stop("unit is null. must be 'meter','milimeter','centimeter','decimeter','kilometer','mile','inch','yard','foot' ")
  }
  
  valid.unit = c("meter","milimeter","centimeter","decimeter","kilometer","mile","inch","yard","foot")
  if(length(valid.unit[valid.unit == tolower(unit)]) == 0){
    stop("invalid unit name. unit name must be 'meter','milimeter','centimeter','decimeter','kilometer','mile','inch','yard','foot' ")
  }
  
  if(segments < 4 || segments > 200){
    stop("segments must be in [4,100]")
  }
  
  res <- .iCall("R_Geometrist_create_buffer", obj@pointer, radius, side, segments, end, unit, prj, PACKAGE="RSuperMap")
  if (is.null(res) || is.logical(res)){
    warning("create geometry buffer failed")
    return(NULL)
  } else{
    return(res)
  }
}

